<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Home SMB Cloud</title>
<script src="jquery-3.3.1.js"></script>
<script src="vue.js"></script>
<style>
*{margin:0;padding:0}
body{font-family: "PingFang SC","Lantinghei SC","Microsoft YaHei",arial,"\5b8b\4f53",sans-serif,tahoma;font-size:14px;}
.message{z-index:1;position:fixed;left:50%;top:10px;transform:translateX(-50%);padding:5px 10px;opacity:0;background:red;color:#fff;transition:opacity 1s;border-radius:3px}
.message.show{opacity:1}
#app{width:65%;margin:50px auto}
a{text-decoration:none;}
ul{border:solid 1px #eee}
li{list-style:none;border-bottom:solid 1px #eee}
ul li:last-child{border-bottom:none}
li a{padding:10px;margin:0 5px;display:block;color:#333}
li a:hover{color:#8a74ff}
.current-path{margin-bottom:10px}
.current-path .path,.current-path a{color:#8a74ff}
li a img{width:24px;vertical-align:middle}
.loading-bar{position: fixed;left: 50%;top: 50%;transform: translateX(-50%) translateY(-50%);background: rgba(255, 255, 255, 1);padding: 10px 15px;box-shadow: 0 0 5px rgba(0, 0, 0, 0.25);}
@-webkit-keyframes loading_ani{	0% {transform:rotate(0deg)}	100% {transform:rotate(360deg)}}
@keyframes loading_ani{	0% {transform:rotate(0deg)}	100% {transform:rotate(360deg)}}
@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}
@keyframes nprogress-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}
.loading-bar em{background:url(loading.svg);width: 42px;height: 42px;display: inline-block;background-size: cover;vertical-align: middle;animation:loading_ani linear infinite 1s;}
.loading-bar span{font-size:14px;}
#nprogress{pointer-events:none}
#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}
#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0,-4px);-ms-transform:rotate(3deg) translate(0,-4px);transform:rotate(3deg) translate(0,-4px)}
#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}
#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:solid 2px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}
.nprogress-custom-parent{overflow:hidden;position:relative}
.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}
</style>
</head>
<body>
<div id="app">
	<div class="message" :class="{show:showMessage}">{{message}}</div>
	<div class="loading-bar" v-if="showLoading">
		<em></em>
		<span>加载中</span>
	</div>
	<div class="list-wrapper">
		<div class="current-path">当前路径: <span class="path">
			<a href="#/">根目录</a>
			<a v-for="item in pathList" :href="'#' + item.path">{{item.name}}</a>
		</span></div>
		<ul>
			<li v-for="item in dataList">
				<a :href="'#' + item.path" v-on:click="getFile(item,$event)">
					<img src="file.svg" alt="" v-if="item.fileType == 'File'" />
					<img src="folder.svg" alt="" v-if="item.fileType == 'Folder'" />
					{{item.name|nameFormat}} <span v-if="item.fileType == 'File'">({{item.size|fileSize}})</span>
				</a>
			</li>
		</ul>
	</div>
</div>
<script>
;(function(root,factory){if(typeof define==='function'&&define.amd){define(factory);}else if(typeof exports==='object'){module.exports=factory();}else{root.NProgress=factory();}})(this,function(){var NProgress={};NProgress.version='0.2.0';var Settings=NProgress.settings={minimum:0.08,easing:'ease',positionUsing:'',speed:200,trickle:true,trickleRate:0.02,trickleSpeed:800,showSpinner:true,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:'body',template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};NProgress.configure=function(options){var key,value;for(key in options){value=options[key];if(value!==undefined&&options.hasOwnProperty(key))Settings[key]=value;}
return this;};NProgress.status=null;NProgress.set=function(n){var started=NProgress.isStarted();n=clamp(n,Settings.minimum,1);NProgress.status=(n===1?null:n);var progress=NProgress.render(!started),bar=progress.querySelector(Settings.barSelector),speed=Settings.speed,ease=Settings.easing;progress.offsetWidth;queue(function(next){if(Settings.positionUsing==='')Settings.positionUsing=NProgress.getPositioningCSS();css(bar,barPositionCSS(n,speed,ease));if(n===1){css(progress,{transition:'none',opacity:1});progress.offsetWidth;setTimeout(function(){css(progress,{transition:'all '+speed+'ms linear',opacity:0});setTimeout(function(){NProgress.remove();next();},speed);},speed);}else{setTimeout(next,speed);}});return this;};NProgress.isStarted=function(){return typeof NProgress.status==='number';};NProgress.start=function(){if(!NProgress.status)NProgress.set(0);var work=function(){setTimeout(function(){if(!NProgress.status)return;NProgress.trickle();work();},Settings.trickleSpeed);};if(Settings.trickle)work();return this;};NProgress.done=function(force){if(!force&&!NProgress.status)return this;return NProgress.inc(0.3+0.5*Math.random()).set(1);};NProgress.inc=function(amount){var n=NProgress.status;if(!n){return NProgress.start();}else{if(typeof amount!=='number'){amount=(1-n)*clamp(Math.random()*n,0.1,0.95);}
n=clamp(n+amount,0,0.994);return NProgress.set(n);}};NProgress.trickle=function(){return NProgress.inc(Math.random()*Settings.trickleRate);};(function(){var initial=0,current=0;NProgress.promise=function($promise){if(!$promise||$promise.state()==="resolved"){return this;}
if(current===0){NProgress.start();}
initial++;current++;$promise.always(function(){current--;if(current===0){initial=0;NProgress.done();}else{NProgress.set((initial-current)/initial);}});return this;};})();NProgress.render=function(fromStart){if(NProgress.isRendered())return document.getElementById('nprogress');addClass(document.documentElement,'nprogress-busy');var progress=document.createElement('div');progress.id='nprogress';progress.innerHTML=Settings.template;var bar=progress.querySelector(Settings.barSelector),perc=fromStart?'-100':toBarPerc(NProgress.status||0),parent=document.querySelector(Settings.parent),spinner;css(bar,{transition:'all 0 linear',transform:'translate3d('+perc+'%,0,0)'});if(!Settings.showSpinner){spinner=progress.querySelector(Settings.spinnerSelector);spinner&&removeElement(spinner);}
if(parent!=document.body){addClass(parent,'nprogress-custom-parent');}
parent.appendChild(progress);return progress;};NProgress.remove=function(){removeClass(document.documentElement,'nprogress-busy');removeClass(document.querySelector(Settings.parent),'nprogress-custom-parent');var progress=document.getElementById('nprogress');progress&&removeElement(progress);};NProgress.isRendered=function(){return!!document.getElementById('nprogress');};NProgress.getPositioningCSS=function(){var bodyStyle=document.body.style;var vendorPrefix=('WebkitTransform'in bodyStyle)?'Webkit':('MozTransform'in bodyStyle)?'Moz':('msTransform'in bodyStyle)?'ms':('OTransform'in bodyStyle)?'O':'';if(vendorPrefix+'Perspective'in bodyStyle){return 'translate3d';}else if(vendorPrefix+'Transform'in bodyStyle){return 'translate';}else{return 'margin';}};function clamp(n,min,max){if(n<min)return min;if(n>max)return max;return n;}
function toBarPerc(n){return(-1+n)*100;}
function barPositionCSS(n,speed,ease){var barCSS;if(Settings.positionUsing==='translate3d'){barCSS={transform:'translate3d('+toBarPerc(n)+'%,0,0)'};}else if(Settings.positionUsing==='translate'){barCSS={transform:'translate('+toBarPerc(n)+'%,0)'};}else{barCSS={'margin-left':toBarPerc(n)+'%'};}
barCSS.transition='all '+speed+'ms '+ease;return barCSS;}
var queue=(function(){var pending=[];function next(){var fn=pending.shift();if(fn){fn(next);}}
return function(fn){pending.push(fn);if(pending.length==1)next();};})();var css=(function(){var cssPrefixes=['Webkit','O','Moz','ms'],cssProps={};function camelCase(string){return string.replace(/^-ms-/,'ms-').replace(/-([\da-z])/gi,function(match,letter){return letter.toUpperCase();});}
function getVendorProp(name){var style=document.body.style;if(name in style)return name;var i=cssPrefixes.length,capName=name.charAt(0).toUpperCase()+name.slice(1),vendorName;while(i--){vendorName=cssPrefixes[i]+capName;if(vendorName in style)return vendorName;}
return name;}
function getStyleProp(name){name=camelCase(name);return cssProps[name]||(cssProps[name]=getVendorProp(name));}
function applyCss(element,prop,value){prop=getStyleProp(prop);element.style[prop]=value;}
return function(element,properties){var args=arguments,prop,value;if(args.length==2){for(prop in properties){value=properties[prop];if(value!==undefined&&properties.hasOwnProperty(prop))applyCss(element,prop,value);}}else{applyCss(element,args[1],args[2]);}}})();function hasClass(element,name){var list=typeof element=='string'?element:classList(element);return list.indexOf(' '+name+' ')>=0;}
function addClass(element,name){var oldList=classList(element),newList=oldList+name;if(hasClass(oldList,name))return;element.className=newList.substring(1);}
function removeClass(element,name){var oldList=classList(element),newList;if(!hasClass(element,name))return;newList=oldList.replace(' '+name+' ',' ');element.className=newList.substring(1,newList.length-1);}
function classList(element){return(' '+(element.className||'')+' ').replace(/\s+/gi,' ');}
function removeElement(element){element&&element.parentNode&&element.parentNode.removeChild(element);}
return NProgress;});
	var net = {
		get(act, param, callback) {
			return $.ajax({
				url: 'interface',
				data: $.extend({
					action: act
				}, param),
				dataType: 'json',
				success: callback,
				error: function() {
					callback({code:-1});
					alert('请求网络数据失败')
				}
			})
		}, 
		timer: null,
		message(msg){
			if (net.timer) {
				clearTimeout(net.timer)
			}
			app.message = msg;
			app.showMessage = true;
			net.timer = setTimeout(() => {
				app.showMessage = false
			}, 3000)
		}
	};
	$(window).on('hashchange', function() {
		var path = location.hash ? location.hash.substr(1) : '/';
		app.loadFile(path);
	});
	var app = new Vue({
		el: '#app',
		data: {
			message: null,
			showMessage: false,
			dataList: [],
			currentPath: '/',
			showLoading:false
		},
		computed: {
			pathList(){
				var ret = [];
				var pathList = this.currentPath.split('/');
				var beforePath = '/';
				for(var i = 1;i < pathList.length - 1;i++){
					ret.push({
						path:beforePath + pathList[i] + '/',
						name:'/ ' + pathList[i]
					});
					beforePath += pathList[i] + '/';
				}
				return ret;
			}
		},
		filters: {
			nameFormat(value) {
				if (!value) return '';
				return value.substr(-1) == '/' ? value.substr(0, value.length - 1) : value
			}, fileSize(value) {
				if (null == value || value == '') {
					return "0 KB"
				}
				var unitArr = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
				var index = 0;
				var srcsize = parseFloat(value);
				index = Math.floor(Math.log(srcsize) / Math.log(1024));
				var size = srcsize / Math.pow(1024, index);
				size = size.toFixed(2);
				return size + unitArr[index]
			}
		},
		methods: {
			loadRoot() {
				location.hash = '/'
			}, getFile(item, e) {
				if (e) e.preventDefault();
				if (item.fileType != 'File') {
					location.hash = item.path
				} else {
					location.href = ('download?path=' + item.path)
				}
			}, loadFile(path) {
				NProgress.start() 
				var xhr = net.get('list', {
					path: path
				}, (ret) => {
					 NProgress.done()
					//this.showLoading = false;
					app.currentPath = path;
					if (ret.code != 0) {
						net.message(ret.message)
					} else {
						this.dataList = ret.data
					}
				})
			}
		}
	});
	$(window).trigger('hashchange');
</script>
</body>
</html>